package com.renfei.cameralibrary.encoder;
/*
 * AudioVideoRecordingSample
 * Sample project to cature audio and video from internal mic/camera and save as MPEG4 file.
 *
 * Copyright (c) 2014-2015 saki t_saki@serenegiant.com
 *
 * File name: MediaVideoEncoder.java
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 * All files in the folder are under this Apache License, Version 2.0.
 */


import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.opengl.EGLContext;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.Surface;

import androidx.annotation.NonNull;

import com.renfei.filterlibrary.gles.EglCore;
import com.renfei.filterlibrary.gles.WindowSurface;
import com.renfei.filterlibrary.glfilter.base.GLImageFilter;
import com.renfei.filterlibrary.glfilter.utils.OpenGLUtils;
import com.renfei.filterlibrary.glfilter.utils.TextureRotationUtils;
import com.renfei.medialibrary.recorder.VideoParams;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.nio.FloatBuffer;

public class MediaVideoEncoder extends MediaEncoder {
    private static final boolean DEBUG = false;    // TODO set false on release
    private static final String TAG = "MediaVideoEncoder";


    private Surface mSurface;
    private VideoParams mVideoParams;


    private RenderHandler mRenderHandler;


    public MediaVideoEncoder(final MediaMuxerWrapper muxer, VideoParams videoParams, final MediaEncoderListener listener) {
        super(muxer, listener);
        if (DEBUG) Log.e(TAG, "MediaVideoEncoder: ");
        this.mVideoParams = videoParams;
        mRenderHandler = RenderHandler.createHandler(TAG);
    }

    private int count = 0;

    public boolean frameAvailableSoon(int texture, long timestamp) {
        boolean result;
        if (result = super.frameAvailableSoon()) {
            Log.e(TAG, "视频帧---:    " + count);
            count++;
        }
        mRenderHandler.drawFrame(texture, timestamp);
        return result;
    }


    @Override
    protected void prepare() throws IOException {
        if (DEBUG) Log.e(TAG, "prepare: ");
        mTrackIndex = -1;
        mMuxerStarted = mIsEOS = false;


        //处理宽高不是2的倍数
        int videoWidth = (mVideoParams.getVideoWidth() % 2 == 0) ? mVideoParams.getVideoWidth() : mVideoParams.getVideoWidth() - 1;
        int videoHeight = (mVideoParams.getVideoHeight() % 2 == 0) ? mVideoParams.getVideoHeight() : mVideoParams.getVideoHeight() - 1;
        final MediaFormat format = MediaFormat.createVideoFormat(VideoParams.MIME_TYPE, videoWidth, videoHeight);
        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);    // API >= 18
        format.setInteger(MediaFormat.KEY_BIT_RATE, mVideoParams.getBitRate());
        format.setInteger(MediaFormat.KEY_FRAME_RATE, VideoParams.FRAME_RATE);
        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, VideoParams.I_FRAME_INTERVAL);
        if (DEBUG) Log.e(TAG, "format: " + format);

        mMediaCodec = MediaCodec.createEncoderByType(VideoParams.MIME_TYPE);
        mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
        mSurface = mMediaCodec.createInputSurface();    // API >= 18

        mRenderHandler.setEglContext(mVideoParams.getEglContext(), mSurface, mVideoParams.getVideoWidth(), mVideoParams.getVideoHeight());


        mMediaCodec.start();
        if (DEBUG) Log.e(TAG, "prepare finishing");
        if (mListener != null) {
            try {
                mListener.onPrepared(this);
            } catch (final Exception e) {
                Log.e(TAG, "prepare:", e);
            }
        }
    }


    @Override
    protected void release() {
        if (DEBUG) Log.e(TAG, "release:");
        if (mSurface != null) {
            mSurface.release();
            mSurface = null;
        }
        if (mRenderHandler != null) {
            mRenderHandler.release();
            mRenderHandler = null;
        }
        super.release();
    }


    @Override
    protected void signalEndOfInputStream() {
        if (DEBUG) Log.d(TAG, "sending EOS to encoder");
        mMediaCodec.signalEndOfInputStream();    // API >= 18
        mIsEOS = true;
    }


}
